/**
  ETFRoot project, Anyang Normal University && IMP-CAS
  \class ETFVMEOfflineSource
  \brief to process VME offline data
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2021-10-02
  \data 2021-10-08 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                   </tr>
  <tr>  <td>2021-10-02   <td>Asia Sun    <td>file created                  </tr>
  </table>

  \copyright Copyright (c) 2021 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#include <iostream>
#include <unistd.h>
#include "ETFVMEOfflineSource.h"
#include "ETFVMEUnpacker.h"
#include "ETFMsg.h"

using std::cout;
using std::endl;

ClassImp(ETFVMEOfflineSource);

ETFVMEOfflineSource::ETFVMEOfflineSource(const string &file) : ETFOfflineSource()
    ,fUnpacker(nullptr){
  SetType(SourceType::kVMESOURCE);
  if(IsVMEFileName(file, true)) fFileName = file;

  if("" == fFileName) ETFMsg::Error("ETFVMEOfflineSource", "ctor: vme file name not set");
  cout << "The input VME file is \033[32;1m" << fFileName << "\033[0m\n" << endl;

  if(access(fFileName.Data(), F_OK))
    ETFMsg::Error("ETFVMEOfflineSource", "ctor: VME file %s not exists", fFileName.Data());
} // end ctor

ETFVMEOfflineSource::~ETFVMEOfflineSource(){}

/// generate a file name for the output root
const TString ETFVMEOfflineSource::ROOTFileName() const{
  char name[256]; strcpy(name, fFileName.Data());
  return TString(basename(name))+"_"+ETFMsg::time0(1)+".root";
} // end member function ROOTFileName

void ETFVMEOfflineSource::FinishEvent(){
  std::cout << "Processing block " << fUnpacker->GetNofProcessedBlock()
            << " event " << fUnpacker->GetNofProcessedEvent() << "\r" << std::flush;
} // end member function FinishEvent

/// open the file, would be called by FairRoot:
/// run->Init()=>fRootManager->Init()=>fSource->Init()
bool ETFVMEOfflineSource::Init(){
  FILE *fp;
  if(!(fp = fopen(fFileName.Data(), "rb")))
    ETFMsg::Error("ETFVMEOfflineSource", "Init: Failed to open input data file %s", fFileName.Data());

  fUnpacker = dynamic_cast<ETFVMEUnpacker *>(fUnpackers->At(0));
  if(!fUnpacker) ETFMsg::Error("ETFVMEOfflineSource", "Init: unpacker is null");

  fMap[fUnpacker] = fp;
  fUnpacker->ReadComment(fp); // skip the first block which contains only comment

  return true;
} // end member function Init
